-- Lua Battle System - 角色系统单元测试

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;src/characters/?.lua;res/data/?.lua'

local TestFramework = require("src.utils.test_framework")
local Logger = require("utils.logger")
local Character = require("characters.character")

local function run_tests()
    local suite = TestFramework.create_suite("Character Unit Tests")

    -- 测试套件设置
    local function setup()
        -- 设置日志级别为debug以查看更多输出
        Logger.init({level = "debug"})
    end

    local function teardown()
        -- 清理测试环境
    end

    suite:setup(setup)
    suite:teardown(teardown)

    -- 测试1：Character模块加载
    suite:add_test("Character module loading", function()
        TestFramework.Assert.is_type("table", Character, "Character should be a table")
        TestFramework.Assert.is_type("function", Character.new, "Character.new should be a function")
    end)

    -- 测试2：角色创建
    suite:add_test("Character creation", function()
        local character_data = {
            id = "test_character_001",
            name = "Test Character",
            level = 5,
            max_hp = 150,
            hp = 150,
            max_mp = 80,
            mp = 80,
            attack = 25,
            defense = 12,
            magic_attack = 18,
            magic_defense = 10,
            speed = 20,
            luck = 12
        }

        local character = Character:new(character_data)

        TestFramework.Assert.is_not_nil(character, "Character should be created successfully")
        TestFramework.Assert.equals("test_character_001", character.id, "Character ID should match")
        TestFramework.Assert.equals("Test Character", character.name, "Character name should match")
        TestFramework.Assert.equals(5, character.level, "Character level should match")
        TestFramework.Assert.equals(150, character.max_hp, "Character max HP should match")
        TestFramework.Assert.equals(150, character.hp, "Character HP should match")
        TestFramework.Assert.equals(80, character.max_mp, "Character max MP should match")
        TestFramework.Assert.equals(80, character.mp, "Character MP should match")
    end)

    -- 测试3：默认属性值
    suite:add_test("Character default attributes", function()
        local character = Character:new()

        TestFramework.Assert.equals("", character.id, "Default ID should be empty string")
        TestFramework.Assert.equals("", character.name, "Default name should be empty string")
        TestFramework.Assert.equals(1, character.level, "Default level should be 1")
        TestFramework.Assert.equals(100, character.max_hp, "Default max HP should be 100")
        TestFramework.Assert.equals(100, character.hp, "Default HP should be 100")
        TestFramework.Assert.equals(50, character.max_mp, "Default max MP should be 50")
        TestFramework.Assert.equals(50, character.mp, "Default MP should be 50")
        TestFramework.Assert.equals(20, character.attack, "Default attack should be 20")
        TestFramework.Assert.equals(10, character.defense, "Default defense should be 10")
        TestFramework.Assert.is_true(character.is_alive, "Default is_alive should be true")
        TestFramework.Assert.is_false(character.is_controlled, "Default is_controlled should be false")
    end)

    -- 测试4：角色属性更新
    suite:add_test("Character attribute updates", function()
        local character = Character:new({
            id = "test_character",
            name = "Test",
            max_hp = 200,
            hp = 180,
            max_mp = 100,
            mp = 75
        })

        -- 测试HP更新
        character:set_hp(150)
        TestFramework.Assert.equals(150, character.hp, "HP should be updated correctly")

        -- 测试MP更新
        character:set_mp(60)
        TestFramework.Assert.equals(60, character.mp, "MP should be updated correctly")

        -- 测试等级更新
        character:set_level(10)
        TestFramework.Assert.equals(10, character.level, "Level should be updated correctly")
    end)

    -- 测试5：HP/MP边界值测试
    suite:add_test("HP/MP boundary values", function()
        local character = Character:new({
            id = "test_character",
            max_hp = 100,
            hp = 100,
            max_mp = 50,
            mp = 50
        })

        -- 测试超过最大值的HP
        character:set_hp(150)
        TestFramework.Assert.equals(100, character.hp, "HP should not exceed max HP")

        -- 测试负数HP
        character:set_hp(-10)
        TestFramework.Assert.equals(0, character.hp, "HP should not be negative")
        TestFramework.Assert.is_false(character.is_alive, "Character should be dead when HP is 0")

        -- 测试超过最大值的MP
        character:set_mp(80)
        TestFramework.Assert.equals(50, character.mp, "MP should not exceed max MP")

        -- 测试负数MP
        character:set_mp(-5)
        TestFramework.Assert.equals(0, character.mp, "MP should not be negative")
    end)

    -- 测试6：状态效果管理
    suite:add_test("Status effects management", function()
        local character = Character:new({id = "test_character"})

        -- 添加状态效果
        character:add_status_effect("poison", {
            name = "中毒",
            duration = 3,
            damage_per_turn = 5
        })

        TestFramework.Assert.is_true(character:has_status_effect("poison"), "Character should have poison status effect")

        -- 检查状态效果数量
        TestFramework.Assert.is_true(#character.status_effects > 0, "Character should have status effects")

        -- 移除状态效果
        character:remove_status_effect("poison")
        TestFramework.Assert.is_false(character:has_status_effect("poison"), "Character should not have poison status effect after removal")
    end)

    -- 测试7：技能管理
    suite:add_test("Skills management", function()
        local character = Character:new({id = "test_character"})

        -- 添加技能
        local skill = {
            id = "basic_attack",
            name = "基础攻击",
            damage = 10,
            cost = { mp = 0 }
        }

        character:add_skill(skill)
        TestFramework.Assert.is_true(character:has_skill("basic_attack"), "Character should have basic_attack skill")

        -- 获取技能
        local retrieved_skill = character:get_skill("basic_attack")
        TestFramework.Assert.is_not_nil(retrieved_skill, "Should retrieve skill successfully")
        TestFramework.Assert.equals("基础攻击", retrieved_skill.name, "Retrieved skill name should match")

        -- 移除技能
        character:remove_skill("basic_attack")
        TestFramework.Assert.is_false(character:has_skill("basic_attack"), "Character should not have skill after removal")
    end)

    -- 测试8：物品管理
    suite:add_test("Items management", function()
        local character = Character:new({id = "test_character"})

        -- 添加物品
        local item = {
            id = "potion",
            name = "治疗药水",
            type = "consumable",
            effect = { heal = 50 }
        }

        character:add_item(item)
        TestFramework.Assert.is_true(character:has_item("potion"), "Character should have potion item")

        -- 获取物品
        local retrieved_item = character:get_item("potion")
        TestFramework.Assert.is_not_nil(retrieved_item, "Should retrieve item successfully")
        TestFramework.Assert.equals("治疗药水", retrieved_item.name, "Retrieved item name should match")

        -- 使用物品
        local initial_hp = character.hp
        character:use_item("potion")
        TestFramework.Assert.is_false(character:has_item("potion"), "Character should not have potion after use")
    end)

    -- 测试9：装备管理
    suite:add_test("Equipment management", function()
        local character = Character:new({id = "test_character"})

        -- 装备武器
        local weapon = {
            id = "sword",
            name = "铁剑",
            type = "weapon",
            attack_bonus = 10,
            defense_bonus = 2
        }

        character:equip_item(weapon, "weapon")
        TestFramework.Assert.is_not_nil(character.equipment.weapon, "Character should have equipped weapon")
        TestFramework.Assert.equals("铁剑", character.equipment.weapon.name, "Equipped weapon name should match")

        -- 检查属性加成
        local attack_with_weapon = character:get_total_attack()
        TestFramework.Assert.is_true(attack_with_weapon > character.attack, "Attack should increase with weapon")

        -- 卸下装备
        character:unequip_item("weapon")
        TestFramework.Assert.is_nil(character.equipment.weapon, "Character should not have equipped weapon after unequip")
    end)

    -- 测试10：生命状态检查
    suite:add_test("Life status checks", function()
        local character = Character:new({
            id = "test_character",
            max_hp = 100,
            hp = 100
        })

        TestFramework.Assert.is_true(character:is_alive(), "Character should be alive initially")

        -- 减少HP到0
        character:take_damage(100)
        TestFramework.Assert.equals(0, character.hp, "HP should be 0 after taking damage")
        TestFramework.Assert.is_false(character:is_alive(), "Character should be dead when HP is 0")

        -- 复活角色
        character:revive()
        TestFramework.Assert.is_true(character:is_alive(), "Character should be alive after revive")
        TestFramework.Assert.is_true(character.hp > 0, "HP should be greater than 0 after revive")
    end)

    -- 运行测试套件
    suite:run()

    -- 返回测试结果
    return TestFramework.get_stats().failed == 0
end

-- 导出测试函数
return {
    run_tests = run_tests
}